﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Googler.Utilities.Web;
using System.Runtime.Serialization.Json;

namespace Googler.Utilities.Mvc
{
    public class MvcHelper
    {
        HttpRequestor _requestor;
        HttpRequestor requestor
        {
            get
            {
                if (_requestor == null) _requestor = new HttpRequestor(); return _requestor;
            }
        }
        public string Host { get; set; }
        string baseUrl { get { return Host.TrimEnd('/') + "/" + Controller + IIS6Extention + "/"; } }
        public string Controller { get; set; }
        public string Username { get; set; }
        public string Password { get; set; }
        public string IIS6Extention
        {
            get { return System.Configuration.ConfigurationManager.AppSettings["Googler.IIS6Extention"] ?? ""; }
        }
        public MvcHelper(string host, string controller, string username, string pwd)
        {
            ValidateUserCredintialsExist(username, pwd);
            this.Username = username;
            this.Password = pwd;
            this.Host = host;
            this.Controller = controller;
        }

        private static void ValidateUserCredintialsExist(string username, string pwd)
        {
            if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(pwd))
                throw new System.Security.SecurityException("Username or Password are EMPTY!!!");

        }
        public string Post(string action, params string[] parameters)
        {
            List<string> tmp = addCredintials(parameters);

            requestor.Open(baseUrl + action, tmp.ToArray());
            StreamReader st = new StreamReader(requestor.PostRequestStreem(), Encoding.UTF8);
            string ret = st.ReadToEnd();
            requestor.Close();

            return ret;
        }

        public T Post<T>(string action)
        {
            List<string> tmp = addCredintials(new string[0]);

            requestor.Open(baseUrl + action, tmp.ToArray());
            T obj = DeserializeJson<T>(requestor.PostRequestStreem());
            requestor.Close();

            return obj;
        }

        /// <summary>
        /// Post Action to Controller
        /// </summary>
        /// <typeparam name="T">The Type of Returned Object</typeparam>
        /// <param name="action">Action to be executed</param>
        /// <param name="parameters">Parameters to action in a form of Key Value</param>
        /// <returns></returns>
        public T Post<T>(string action, params string[] parameters)
        {
            List<string> tmp = addCredintials(parameters);
            requestor.Open(baseUrl + action, tmp.ToArray());
            T obj = DeserializeJson<T>(requestor.PostRequestStreem());
            requestor.Close();

            return obj;
        }

        public static T DeserializeJson<T>(System.IO.Stream st)
        {
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
            T obj = (T)ser.ReadObject(st);
            return obj;
        }

        public static T DeserializeJson<T>(string json)
        {
            return DeserializeJson<T>(new MemoryStream(Encoding.UTF8.GetBytes(json)));
        }

        public static string SerializeToJson(object obj)
        {
            System.IO.MemoryStream ms = new MemoryStream();
            DataContractJsonSerializer ser = new DataContractJsonSerializer(obj.GetType());
            ser.WriteObject(ms, obj);
            string ret = GetString(ms.ToArray());
            return ret;
        }

        private static string GetString(byte[] byt)
        {
            return Encoding.UTF8.GetString(byt);
        }

        public static string HttpEncode(string text)
        {
            return System.Web.HttpUtility.UrlEncode(text, Encoding.UTF8);
        }

        public static string Decode(string text)
        {
            return text;
            //return System.Web.HttpUtility.UrlDecode(text, UTF8Encoding.Default);
        }
        private List<string> addCredintials(string[] parameters)
        {
            ValidateUserCredintialsExist(Username, Password);
            List<string> tmp = new List<string>(parameters.Length + 4);
            tmp.AddRange(new string[] { "un", Username, "pwd", Password });
            tmp.AddRange(parameters);
            return tmp;
        }
    }
}
